<template>
  <div ref="refEcharts" class="echarts-wrapper" />
</template>

<script>
import {
  watch,
  computed,
  defineComponent,
  reactive,
  ref,
  shallowRef,
  toRefs,
  onMounted,
  onBeforeUnmount,
} from "vue";
import * as echarts from "echarts";

export default defineComponent({
  name: "VueChart",
  props: {
    options: {
      type: Object,
      required: true,
      default() {
        return {};
      },
    },
  },
  emits: ["chartMouseover", "chartMouseout"],
  setup(props, { emit }) {
    const refEcharts = ref();
    // data
    let chart = null;
    const state = reactive({
      minScreenWidth: 1280,
      resizeFrame: undefined,
      currentScreenWidth: 0,
      currentScreenHeight: 0,
      listenScreenHeight: true,
      timer: null,
    });

    const renderChart = () => {
      if (chart) {
        chart.clear();
        chart.setOption(props.options);
      }
    };

    const resizeChart = () => {
      if (chart) {
        const nowScreenWidth = document.body.clientWidth;
        const nowScreenHeight = document.body.clientHeight;
        if (
          nowScreenWidth >= state.minScreenWidth &&
          nowScreenWidth !== state.currentScreenWidth
        ) {
          chart.resize();
          state.currentScreenWidth = nowScreenWidth;
          state.currentScreenHeight = nowScreenHeight;
          return;
        }
        if (
          state.listenScreenHeight &&
          nowScreenHeight !== state.currentScreenHeight
        ) {
          chart.resize();
          state.currentScreenWidth = nowScreenWidth;
          state.currentScreenHeight = nowScreenHeight;
        }
      }
      state.resizeFrame = undefined;
    };

    const frameTest = () => {
      if (state.resizeFrame) {
        window.cancelAnimationFrame(state.resizeFrame);
      }
      state.resizeFrame = window.requestAnimationFrame(resizeChart);
    };

    const initChart = () => {
      if (chart) {
        return;
      }
      chart = echarts.init(refEcharts.value);
      chart.on("mouseover", (value) => {
        emit("chartMouseover", value);
      });
      chart.on("mouseout", (value) => {
        emit("chartMouseout", value);
      });
    };

    onMounted(() => {
      initChart();
      renderChart();
      window.addEventListener("resize", frameTest, false);
    });

    onBeforeUnmount(() => {
      if (chart) {
        chart.dispose();
        chart = undefined;
      }
      if (state.resizeFrame) {
        window.cancelAnimationFrame(state.resizeFrame);
        state.resizeFrame = undefined;
      }
      window.removeEventListener("resize", frameTest);
    });

    watch(() => props.options, renderChart);

    return {
      refEcharts,
    };
  },
});
</script>

<style lang="less" scoped>
.echarts-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
}
</style>
